// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Amphibiantrading

//@version=5
indicator("Auto Anchored Swing VWAP's", overlay = true, shorttitle = 'ASV')

//----------enum----------//
enum lineStyle 
    solid = 'Solid'
    dashed = 'Dashed'
    dotted = 'Dotted'

//----------settings----------//
vsrc    = input.source(ohlc4, 'VWAP Source', display = display.none)
pivLen  = input.int(9, 'Swing Lookback')
showph  = input.bool(true, 'Swing High VWAP', inline = '1')
phCol   = input.color(color.green, '', inline = '1')
phWdith = input.int(2, '', inline = '1')
phStyle = input.enum(lineStyle.solid, ' ', inline = '1')
showpl  = input.bool(true, 'Swing Low VWAP ', inline = '2')
plCol   = input.color(color.blue, '', inline = '2')
plWdith = input.int(2, '', inline = '2')
plStyle = input.enum(lineStyle.solid, ' ', inline = '2')

//----------type----------//
type vwapData
    float [] vol 
    float [] pv 
    float [] vwaps
    int startBar
    chart.point fbs
    chart.point [] cps
    polyline vwapLine

//----------methods----------//
method popper(array<vwapData> this)=>
    if this.size() > 0
        this.last().vwapLine.delete()
        this.pop()

method vwapper(array<vwapData> this, lineCol, lineW, lineS)=>
    if this.size() > 0
        s = this.first()
        if bar_index > s.startBar
            s.vol.push(s.vol.get(0) + volume)
            s.vol.shift()
            s.pv.push(s.pv.get(0) + vsrc * volume)
            s.pv.shift()
            s.vwaps.unshift(s.pv.get(0)/s.vol.get(0))

            s.cps.clear()
            for i = 0 to s.vwaps.size()-1
                s.cps.push(chart.point.from_index(bar_index[i], s.vwaps.get(i)))
            s.cps.push(s.fbs)
            s.vwapLine.delete()
            s.vwapLine := polyline.new(s.cps, line_color = lineCol, line_width = lineW, line_style = lineS)

method styler(lineStyle style)=>
    switch style
        lineStyle.solid => line.style_solid
        lineStyle.dashed => line.style_dashed
        lineStyle.dotted => line.style_dotted

//----------variables----------//
var phArr   = array.new<vwapData>()
var plArr   = array.new<vwapData>()
ph          = ta.pivothigh(pivLen,pivLen)
pl          = ta.pivotlow(pivLen,pivLen)

//----------conditions----------//
if not na(ph)
    phArr.popper()
    phArr.unshift(vwapData.new(array.new<float>(1, volume[pivLen]), array.new<float>(1, volume[pivLen]*vsrc[pivLen]),array.new<float>(), bar_index, chart.point.from_index(bar_index[pivLen],(volume[pivLen]*vsrc[pivLen])/volume[pivLen]), array.new<chart.point>()))
    new = phArr.first()
    for i = pivLen-1 to 0
        new.vol.push(new.vol.first()+volume[i])
        new.vol.shift()
        new.pv.push(new.pv.first() + (vsrc[i] * volume[i]))
        new.pv.shift()
        new.vwaps.unshift(new.pv.first()/new.vol.first())

if not na(pl)
    plArr.popper()
    plArr.unshift(vwapData.new(array.new<float>(1, volume[pivLen]), array.new<float>(1, volume[pivLen]*vsrc[pivLen]),array.new<float>(), bar_index, chart.point.from_index(bar_index[pivLen],(volume[pivLen]*vsrc[pivLen])/volume[pivLen]), array.new<chart.point>()))
    new = plArr.first()
    for i = pivLen-1 to 0
        new.vol.push(new.vol.first()+volume[i])
        new.vol.shift()
        new.pv.push(new.pv.first() + (vsrc[i] * volume[i]))
        new.pv.shift()
        new.vwaps.unshift(new.pv.first()/new.vol.first())

//----------vwap line management----------//
if showph
    phArr.vwapper(phCol, phWdith, phStyle.styler())
if showpl
    plArr.vwapper(plCol, plWdith, plStyle.styler())
